﻿using System;
using MugenMvvmToolkit.Ioc;

namespace MugenMvvmToolkit.Models
{
    /// <summary>
    ///     Represents an information about binding.
    /// </summary>
    public struct BindingInfo<T>
    {
        #region Fields

        /// <summary>
        ///     Gets the empty instance of BindingInfo.
        /// </summary>
        public static readonly BindingInfo<T> Empty = default(BindingInfo<T>);

        /// <summary>
        ///     Gets the constant instance.
        /// </summary>
        public readonly T Instance;

        /// <summary>
        ///     Gets the dependecy lifecycle of service.
        /// </summary>
        public readonly DependencyLifecycle Lifecycle;

        /// <summary>
        ///     Gets the type of service.
        /// </summary>
        public readonly Type Type;

        #endregion

        #region Constructors

        /// <summary>
        ///     Initializes a new instance of the <see cref="BindingInfo{T}" /> class.
        /// </summary>
        internal BindingInfo(T instance, Type type, DependencyLifecycle lifecycle)
        {
            Instance = instance;
            Type = type;
            Lifecycle = lifecycle;
        }

        #endregion

        #region Properties

        internal bool IsEmpty
        {
// ReSharper disable once CompareNonConstrainedGenericWithNull
            get { return Instance == null && Type == null; }
        }

        #endregion

        #region Methods

        /// <summary>
        ///     Creates an instance of BindingInfo from an instance of service.
        /// </summary>
        public static BindingInfo<T> FromInstance(T instance)
        {
            Should.NotBeNull(instance, "instance");
            return new BindingInfo<T>(instance, null, DependencyLifecycle.SingleInstance);
        }

        /// <summary>
        ///     Creates an instance of BindingInfo from a type of service.
        /// </summary>
        public static BindingInfo<T> FromType<TService>(
            DependencyLifecycle lifecycle = DependencyLifecycle.TransientScopeInstance)
        {
            return new BindingInfo<T>(default(T), typeof (TService), lifecycle);
        }

        /// <summary>
        ///     Creates an instance of BindingInfo from a type of service.
        /// </summary>
        public static BindingInfo<T> FromType(Type serviceType,
            DependencyLifecycle lifecycle = DependencyLifecycle.TransientScopeInstance)
        {
            Should.NotBeNull(serviceType, "serviceType");
            Should.BeOfType<T>(serviceType, "serviceType");
            return new BindingInfo<T>(default(T), serviceType, lifecycle);
        }

        #endregion
    }
}